Categories
JavaScript Best Practices

JavaScript Best Practices — Modules

Spread the love

JavaScript is a very forgiving language. It’s easy to write code that runs but has mistakes in it.

In this article, we’ll look at some best practices for importing and exporting from JavaScript modules.

Only Import From a Path in One Place

If we import multiple members from one module, then all members should be imported in one import statement.

For instance, instead of writing the following code to import members:

module.js

export const foo = 1;
export const bar = 2;

index.js

import { foo } from "./module";
import { bar } from "./module";
console.log(foo, bar);

In the code above, we have 2 lines to import 2 different members from the same module. That’s no good since we have lots of duplicate code in one place.

Instead, we should just put them all in the same module to save space and remove duplicate code.

For example, we can instead write the following:

module.js

export const foo = 1;
export const bar = 2;

index.js

import { foo, bar } from "./module";
console.log(foo, bar);

In the code above, we imported the members of module.js in index.js all in one line. As we can see, we saved lots of typing and duplication since we combined the 2 lines into one.

Do Not Export Mutable Bindings

We shouldn’t export mutable entities because we don’t want to accidentally change them inside the module that it’s export from. For instance, if we have the following code:

module.js

export let foo = 1;
foo = 3;
export const bar = 2;

index.js

import { foo, bar } from "./module";
console.log(foo, bar);

In the code above, we exported the foo member from module.js and then change the value of foo later.

Then when we import foo in index.js , we see that the value 3 is logged for foo .

Therefore whenever we change the value by reassigning it, the new value will be exported.

Therefore, we shouldn’t export members that have been defined with let since these changes may be hidden if we import it from a library and not code that we edit usually.

If foo is defined with const then we wouldn’t be able to reassign it to a new value after we export it.

In Modules With a Single Export, Prefer Default Export Over Named Export

If we have only one member to export in a module, then we should just export it as a default export.

The advantage of that is that we can name it whatever we want when we import it without the as keyword.

For instance, instead of writing the following:

module.js

export const bar = 2;

index.js

import { bar as foo } from "./module";
console.log(foo);

We can write the following instead:

module.js

const bar = 2;
export default bar;

index.js

import foo from "./module";
console.log(foo);

In the second example, we exported bar as a default export. Then in index.js , we can import it with the name foo or any name instead of the name bar without using the as keyword.

This is convenient to avoid name clashes with imports if we have lots of imports.

Put All Imports Above Non-Import Statements

Imports should be above non-import statements since this makes everyone clear where the exports are.

For instance, instead of writing the following code:

bar.js

export const bar = 1;

module.js

export const foo = 2;

index.js

import { foo } from "./module";
console.log(foo);

import { bar } from "./bar";
console.log(bar);

In the code above, we imported items from 2 different modules in index.js and the 2 import statements are far from each other.

We have the foo import separated from the bar import with a console.log call.

Import statements being scattered makes finding them hard.

Instead, we should write the following:

import { foo } from "./module";
import { bar } from "./bar";

console.log(foo, bar);

to group all the import statements at the top of our code file.

Conclusion

We should group import statements together so that they can easily find the imports from the top of the code.

If we have only one member to export, then we can just export it as a default.

Also, we should export mutable bindings since they can be changed after they’re exported.

By John Au-Yeung

Web developer specializing in React, Vue, and front end development.

Leave a Reply

Your email address will not be published. Required fields are marked *